#include"q_selected_edit_tool.h"
#include"points.h"
#include<math.h>
QSelectEditTool::QSelectEditTool(QObject *parent):QMyTool(parent),currentItem(0)
{
	int x=0;
	int y=0;
	int w=50;
	int h=60;
	topleftpoint=new TopLeftPoint(x-w/2,y-h/2,this);
	toprightpoint=new TopRightPoint(x+w/2,y-h/2,this);
	bottomleftpoint=new BottomLeftPoint(x-w/2,y+h/2,this);
	bottomrightpoint=new BottomRightPoint(x+w/2,y+h/2,this);
	rotationcenterpoint=new RotationCenterPoint(x,y,this);
	rotationcontrolpoint=new RotationControlPoint(x,y-h,this);
	topcenterpoint=new TopCenterPoint(x,y-h/2,this);
	rightcenterpoint=new RightCenterPoint(x+w/2,y,this);
	this->State=toolState::initinalState;
	this->ObjectIndex=0;
	this->time=0;
	this->sent=false;
}
QSelectEditTool::~QSelectEditTool()
{
}
void QSelectEditTool::showPoints()
{
	rotationcenterpoint->setZValue(this->currentItem->zValue()+1);
	this->topleftpoint->show();
	this->toprightpoint->show();
	this->bottomleftpoint->show();
	this->bottomrightpoint->show();
	this->rotationcenterpoint->show();
	this->rotationcontrolpoint->show();
	this->topcenterpoint->show();
	this->rightcenterpoint->show();
}
void QSelectEditTool::hidePoints()
{
	this->topleftpoint->hide();
	this->toprightpoint->hide();
	this->bottomleftpoint->hide();
	this->bottomrightpoint->hide();
	this->rotationcenterpoint->hide();
	this->rotationcontrolpoint->hide();
	this->topcenterpoint->hide();
	this->rightcenterpoint->hide();
}
bool QSelectEditTool::SetController(centralController* c)
{
	if(c){
		controller=c;
		return true;
	}
	else
		return false;
}
void QSelectEditTool::updatePoints()
{
	QPointF ntlp=this->currentItem->mapToScene(this->tlp);
	
	QPointF ntrp=this->currentItem->mapToScene(this->trp);
	
	
	QPointF nblp=this->currentItem->mapToScene(this->blp);
	
	QPointF nbrp=this->currentItem->mapToScene(this->brp);
	
	QPointF nrcp=this->currentItem->mapToScene(this->rcp);
	
	QPointF nrconp=this->currentItem->mapToScene(this->rconp);

	QPointF ntcp=QPointF((ntlp.x()+ntrp.x())/2,(ntlp.y()+ntrp.y())/2);
	QPointF nrcep=QPointF((nbrp.x()+ntrp.x())/2,(nbrp.y()+ntrp.y())/2);
	this->rotationcenterpoint->setPos(nrcp);
	
	 /* rcp=currentItem->mapFromScene(nrcp);
		AxisTrans=QTransform(1,0,0,1,rcp.x(),rcp.y());
		Translation=QTransform(1,0,0,1,-nrcp.x(),-nrcp.y())*/;


	this->bottomrightpoint->setPos(nbrp);
	this->bottomleftpoint->setPos(nblp);
	this->toprightpoint->setPos(ntrp);
	this->topleftpoint->setPos(ntlp);
	this->rotationcontrolpoint->setPos(nrconp);
	this->topcenterpoint->setPos(ntcp);
	this->rightcenterpoint->setPos(nrcep);
}
void QSelectEditTool::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
	
	if(this->Container->mouseGrabberItem())
	{
		this->sent=true;
		QGraphicsItem* it=this->Container->mouseGrabberItem();
		int o=it->type();
		bool isedit=(o==TopLeftPoint::Type)||(o==TopRightPoint::Type)||(o==BottomLeftPoint::Type)||(o==BottomRightPoint::Type)||(o==TopCenterPoint::Type)||(o==RightCenterPoint::Type)||(o==RotationCenterPoint::Type)||(o==RotationControlPoint::Type);
		if(isedit)
		{
			toolState next=this->getNextState(this->State,mouseAction::pressControlAction);
			
			//toolAction act=this->getNextAction(this->State,mouseAction::pressControlAction);
			//this->excute(act);


			this->State=next;
			return;
		}
		else
		{
			toolState next=this->getNextState(this->State,mouseAction::pressObjectAction);
			
			//t//oolAction act=this->getNextAction(this->State,mouseAction::pressObjectAction);
			//this->excute(act);


			this->State=next;
			/*if(!this->topleftpoint->scene())
			{
				int w=0;
				int h=0;
				int y=0;
				int x=0;
				topleftpoint=new TopLeftPoint(x-w/2,y-h/2,this);
	            toprightpoint=new TopRightPoint(x+w/2,y-h/2,this);
	              bottomleftpoint=new BottomLeftPoint(x-w/2,y+h/2,this);
	             bottomrightpoint=new BottomRightPoint(x+w/2,y+h/2,this);
	             rotationcenterpoint=new RotationCenterPoint(x,y,this);
	             rotationcontrolpoint=new RotationControlPoint(x,y-h,this);
	                  topcenterpoint=new TopCenterPoint(x,y-h/2,this);
	                 rightcenterpoint=new RightCenterPoint(x+w/2,y,this);
				this->initinal();
			}*/
			this->cleardata();
			this->controller->receiveMessage(new CancleCurrentEditObjectsMessage());
			
			this->currentItem=(this->Container->mouseGrabberItem());
			this->currentItem->setFlag(QGraphicsItem::ItemIsMovable);
			this->time=this->Container->CurrentTime();
			this->ObjectIndex=this->Container->ItemIndex(this->currentItem);
			
			this->controller->receiveMessage(new SelectObjectsMessage(SelectObjectsArgs(ObjectIndex)));
			if(this->controller->GetNodeType(ObjectIndex)==Path){
				return;}


			//this->controller->receiveMessage(new SelectObjectsMessage(ObjectIndex));
			//int nodeindex=0;//this->controller->ObjectIndexUnderPointAt(mouseEvent->pos())[0];
	//const DisplayNode* currentnode=this->controller->GetObjectByIndex(nodeindex);
	qreal wposx=this->controller->GetValueByIndex(this->ObjectIndex,posx,time);
	qreal wposy=this->controller->GetValueByIndex(this->ObjectIndex,posy,time);
	qreal waxisx=this->controller->GetValueByIndex(this->ObjectIndex,axisx,time);
	qreal waxisy=this->controller->GetValueByIndex(this->ObjectIndex,axisy,time);
	qreal wskewx=this->controller->GetValueByIndex(this->ObjectIndex,skewx,time);
	qreal wskewy=this->controller->GetValueByIndex(this->ObjectIndex,skewy,time);
	qreal rotation=this->controller->GetValueByIndex(this->ObjectIndex,angle,time);
	qreal wscalex=this->controller->GetValueByIndex(this->ObjectIndex,scalex,time);
	qreal wscaley=this->controller->GetValueByIndex(this->ObjectIndex,scaley,time);
	this->Translation=QTransform(1,0,0,1,wposx,wposy);


	double newSkx=(wskewx*3.1415926/180);
	qreal newtgx=tan(newSkx);
	double newSky=(wskewy*3.1415926/180);
	qreal newtgy=tan(newSky);

	this->Skew=QTransform(1,newtgy,newtgx,1,0,0);
	qreal ra=rotation*3.1415926/180;
	this->Rotation=QTransform(cos(ra),sin(ra),-sin(ra),cos(ra),0,0);
	this->Scale=QTransform(wscalex,0,0,wscaley,0,0);
	QPointF axis=QPointF(waxisx,waxisy);
	//axis=this->currentItem->mapFromScene(axis);
	this->AxisTrans=QTransform(1,0,0,1,-waxisx,-waxisy);
	QPointF q=this->currentItem->pos();
	this->tlp=this->currentItem->boundingRect().topLeft();
	this->trp=this->currentItem->boundingRect().topRight();
	this->blp=this->currentItem->boundingRect().bottomLeft();
	this->brp=this->currentItem->boundingRect().bottomRight();
	this->rcp=axis;
	this->oriheight=this->currentItem->boundingRect().height();
	this->oriwidth=this->currentItem->boundingRect().width();
	QPointF rcontrol=QPointF((tlp.x()+trp.x())/2,tlp.y()-oriheight/3);
	this->rconp=rcontrol;
	updatePoints();
	//this->initinal();
	emit showPropertys(ObjectIndex);
	this->showPoints();
		}
	}else
	{

		emit this->clearProperty();

		//this->currentItem->setFlag(QGraphicsItem::ItemIsMovable,false);
		this->hidePoints();
		return ;
	}
	
	//QGraphicsScene::mousePressEvent(mouseEvent);
}
void QSelectEditTool::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
	if(this->Container->mouseGrabberItem())
	{
		toolState next=this->getNextState(this->State,mouseAction::moveAction);
			
	//toolAction act=this->getNextAction(this->State,mouseAction::moveAction);
	//this->excute(act);
	this->State=next;
		QGraphicsItem* it=this->Container->mouseGrabberItem();
		int o=it->type();
		bool isedit=(o==TopLeftPoint::Type)||(o==TopRightPoint::Type)||(o==BottomLeftPoint::Type)||(o==BottomRightPoint::Type)||(o==TopCenterPoint::Type)||(o==RightCenterPoint::Type)||(o==RotationCenterPoint::Type)||(o==RotationControlPoint::Type);
		if(!isedit){

			updatePoints();
		}
	}
	


}
void QSelectEditTool::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
{

	QList<QGraphicsItem *>	selected=this->Container->selectedItems();
	if(selected.size()!=0)
	{
		this->currentItem->setFlag(QGraphicsItem::ItemIsMovable,false);
		this->updatePoints();
		if(this->State==toolState::editState||this->State==toolState::moveObjectState)
			{
				this->sendMessage();
		     emit showPropertys(ObjectIndex);}
		
		//if(this->State==toolState::enterToChildState)
		//{

		//}
	}
	toolState next=this->getNextState(this->State,mouseAction::releaseMouse);
			
//	toolAction act=this->getNextAction(this->State,mouseAction::releaseMouse);
	//this->excute(act);
	this->State=next;
}
void QSelectEditTool::sendMessage()
{
	this->controller->receiveMessage(new SelectObjectsMessage(SelectObjectsArgs(ObjectIndex)));
	QPointF a=this->rcp;
	qreal waxisx=a.x();
	qreal waxisy=a.y();
	SetArgs args=SetArgs(axisx,waxisx,time);
	Message* m1=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m1);
	args.propertype=axisy;
	args.value=waxisy;
	Message* m2=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m2);
	qreal wskewx=this->Skew.m21();
	qreal wskewy=this->Skew.m12();

	qreal nwsx=atan(wskewx);
	qreal axx=nwsx*180/3.1415926;

	args.propertype=skewx;
	args.value=-axx;
	
	Message* m3=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m3);


	qreal nwsy=atan(wskewy);
	qreal ayy=nwsy*180/3.1415926;

	args.propertype=skewy;
	args.value=-ayy;
	Message* m4=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m4);
	qreal cost=this->Rotation.m11();
	qreal sint=this->Rotation.m12();
	qreal tg=sint/cost;
	qreal r=atan(tg);
	if(r>=0)
	{
		if(cost<0)
			r=r+acos(-1.0);
	}
	else
	{
		if(cost<0)
			r=r+acos(-1.0);
	}
	if(cost==0&&sint==1)
		r=acos(0.0);
	if(cost==0&&sint==-1)
		r=-acos(0.0);
	qreal wangle=r*180/3.1415926;
	args.propertype=angle;
	args.value=wangle;
	Message* m5=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m5);
	qreal wscalex=this->Scale.m11();
	qreal wscaley=this->Scale.m22();
	args.propertype=scalex;
	args.value=wscalex;
	Message* m6=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m6);
	args.propertype=scaley;
	args.value=wscaley;
	Message* m7=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m7);
	QPointF pos=this->currentItem->mapToScene(a);
	qreal wposx=pos.x();
	qreal wposy=pos.y();
	args.propertype=posx;
	args.value=wposx;
	Message* m8=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m8);
	args.propertype=posy;
	args.value=wposy;
	Message* m9=new SetPropertyValueMessage(args);
	this->controller->receiveMessage(m9);
	emit showPropertys(ObjectIndex);

}
void QSelectEditTool::initinal()
{

	this->Container->addItem(topleftpoint);
	this->Container->addItem(toprightpoint);
	this->Container->addItem(bottomleftpoint);
	this->Container->addItem(bottomrightpoint);
	this->Container->addItem(rotationcenterpoint);
	//rotationcenterpoint->setZValue(this->currentItem->zValue()+1);
	this->Container->addItem(rotationcontrolpoint);
	this->Container->addItem(topcenterpoint);
	this->Container->addItem(rightcenterpoint);
	this->hidePoints();
}
void refresh()
{
	
}
void QSelectEditTool::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent )
{
	if(this->Container->mouseGrabberItem())
	{
		toolState next=this->getNextState(this->State,mouseAction::doubleClickAction);
			
	   // toolAction act=this->getNextAction(this->State,mouseAction::moveAction);
	//this->excute(act);
	    this->State=next;
		emit this->clearProperty();
		QGraphicsItem* it=this->Container->mouseGrabberItem();
		int o=it->type();
		bool isedit=(o==TopLeftPoint::Type)||(o==TopRightPoint::Type)||(o==BottomLeftPoint::Type)||(o==BottomRightPoint::Type)||(o==TopCenterPoint::Type)||(o==RightCenterPoint::Type)||(o==RotationCenterPoint::Type)||(o==RotationControlPoint::Type);
		if(isedit)
			return;
		else
		{
			this->currentItem=(this->Container->mouseGrabberItem());
			this->sent=false;
			this->time=this->Container->CurrentTime();
			this->ObjectIndex=this->Container->ItemIndex(this->currentItem);
			const DisplayNode* node=this->controller->GetObjectByIndex(ObjectIndex);
			if(node->IsAtomic())
				return;
			QWidget* currentTab;
			//emit getCurrentTabWidget(currentTab);
			QString p="ghj";
			//emit getCurrentTabPath(p,currentTab);
			//QString p=this->Container->mainwindow->tabToNode[this->Container->mainwindow->currentWidget()];
			emit this->getCurrentContainerPath(p);
			QVector<int>path=QVector<int>();
			for(int i=0;i!=p.size();i++)
			{
				int j=int(p[i].toAscii()-'0');
				path.push_back(j);
			}
			path.push_back(ObjectIndex);
			//path.pop_front();
			nodePath thepath=nodePath(path);
			QToolGraphicsScene* scene=new QToolGraphicsScene(0,0,1000,1000);
			scene->SetController(this->controller);
			scene->SetCurrentContainer(thepath);
			//thepath.path.push_front(0);
			this->controller->receiveMessage(new SelectContainerMessage(thepath));
			emit addNewTab(scene,thepath.path);
			
		}
	}else
	{
	
		return ;
	}
}
void QSelectEditTool::cleardata()
{
	this->Translation=QTransform();
	this->Skew=QTransform();
	this->Scale=QTransform();
	this->AxisTrans=QTransform();;
	this->Rotation=QTransform();
}
void QSelectEditTool::Initialize()
{
	int w=0;
				int h=0;
				int y=0;
				int x=0;
				topleftpoint=new TopLeftPoint(x-w/2,y-h/2,this);
	            toprightpoint=new TopRightPoint(x+w/2,y-h/2,this);
	              bottomleftpoint=new BottomLeftPoint(x-w/2,y+h/2,this);
	             bottomrightpoint=new BottomRightPoint(x+w/2,y+h/2,this);
	             rotationcenterpoint=new RotationCenterPoint(x,y,this);
	             rotationcontrolpoint=new RotationControlPoint(x,y-h,this);
	                  topcenterpoint=new TopCenterPoint(x,y-h/2,this);
	                 rightcenterpoint=new RightCenterPoint(x+w/2,y,this);
					 this->initinal();
					 this->hidePoints();
}
toolState QSelectEditTool::getNextState(toolState cur,mouseAction mact)
{
	toolState r=cur;
	switch(cur){
	case initinalState:
		{
			if(mact==mouseAction::pressNothigAction)
				r=cur;
			if(mact==mouseAction::pressObjectAction)
				r=toolState::selectObjectState;
			break;
		}
	case selectObjectState:
		{
			if(mact==mouseAction::releaseMouse)
				r=cur;
			if(mact==mouseAction::moveAction)
				r=toolState::moveObjectState;
			if(mact==mact==mouseAction::pressControlAction)
				r=toolState::selectControlState;
			if(mact==mouseAction::doubleClickAction)
				r=toolState::enterToChildState;
			if(mact==mouseAction::pressNothigAction)
				r=toolState::initinalState;
			break;
		}
	case moveObjectState:
		{
			if(mact==mouseAction::releaseMouse)
				r=toolState::selectControlState;
			break;
		}
	case enterToChildState:
		{
			r=toolState::selectObjectState;
			break;
		}
	case selectControlState:
		{
			if(mact==mouseAction::pressObjectAction)
				r=toolState::selectObjectState;
			if(mact==mouseAction::moveAction)
				r=toolState::editState;
			if(mact==mouseAction::pressNothigAction)
				r=toolState::initinalState;
			break;
		}
	case editState:
		{
			if(mact==mouseAction::releaseMouse)
				r=toolState::selectControlState;
			break;
		}
	}
	return r;
}
void QSelectEditTool::Finalize()
{
	this->controller->receiveMessage(new CancleCurrentEditObjectsMessage());
	this->State=toolState::initinalState;
}